home *** CD-ROM | disk | FTP | other *** search
- /* file make.c */
- /* simplified "make" for ms-dos */
- /* from usenet posting. */
-
- long dateof(), max(), min(), make();
- unsigned char *envfind();
-
- #include <stdio.h>
- #include "bdos.h"
-
- #define ERROR -1
- #define TRUE 1
- #define FALSE 0
-
- #define DEFAULT "MAKEFILE"
- #define INMAX 130 /* maximum input line length */
-
- #define DEPENDANT 1 /* used in calling getmodified */
- #define DEFINED 2
-
- struct howrec {
- char *howcom,*howargs;
- struct howrec *nexthow;
- };
-
- struct deprec {
- char *name;
- struct defnrec *def;
- struct deprec *nextdep;
- };
-
- struct defnrec {
- char *name;
- int uptodate;
- long modified;
- struct deprec *dependson;
- struct howrec *howto;
- struct defnrec *nextdefn;
- };
-
- struct dorec {
- char *name;
- struct dorec *nextdo;
- };
-
- struct defnrec *defnlist;
- struct dorec *dolist;
-
- int execute;
- int stopOnErr;
- int madesomething;
- int knowhow;
- int no_file;
-
- main(argc,argv)
- int argc;
- char *argv[];
- {
-
-
-
- no_file = 1;
- set_dta();
-
- init(argc,argv);
-
- /* now fall down the dolist and do them all */
-
- while (dolist != NULL) {
- madesomething = FALSE;
-
- make(dolist->name);
-
- if (!madesomething) {
- if (knowhow) {
- fprintf(stderr,"Make: '%s' is up to date.",dolist->name);
- } else {
- fprintf(stderr,
- "Make: Don't know how to make '%s'.",dolist->name);
- if (stopOnErr)
- exit(-1);
- }
- }
- dolist = dolist->nextdo;
- }
-
- }
-
-
- init(argc,argv)
- int argc;
- char *argv[];
- {
- int i, usedefault;
- dolist = NULL;
- defnlist = NULL;
- usedefault = TRUE;
- execute = TRUE;
- stopOnErr = TRUE;
-
- for (i=1; i < argc; i++) {
- if (argv[i][0] == '-') { /* option */
- switch (argv[i][1]) {
- case 'f': case 'F': /* arg following is a makefile */
- if (++i < argc) {
- readmakefile(argv[i]);
- usedefault = FALSE;
- } else {
- fprintf(stderr,"Make: '-f' requires filename");
- exit(-1);
- }
- break;
- case 'i': case 'I': /* ignore errors on execution */
- stopOnErr = FALSE;
- break;
- case 'n': case 'N': /* don't execute commands - just print */
- execute = FALSE;
- break;
- default:
- fprintf(stderr,"Make: unknown option '%s'.",argv[i]);
- }
- } else { /* it must be something to make */
- add_do(argv[i]);
- no_file = 0;
- }
- }
- if (usedefault)
- readmakefile(DEFAULT);
-
- }
-
- long make(s) /* returns the modified date/time */
- char *s;
- {
- struct defnrec *defnp;
- struct deprec *depp;
- struct howrec *howp;
- long latest, getmodified(), max();
-
- /* look for the definition */
- defnp = defnlist;
-
- while (defnp != NULL) {
- if (strcmp(defnp->name,s) == 0)
- break;
- defnp = defnp->nextdefn;
- }
-
- if (defnp == NULL) { /* don't know how to make it */
- knowhow = FALSE;
- latest = getmodified(s,DEFINED);
- if (latest==0) { /* doesn't exist but don't know how to make */
- fprintf(stderr,"Make: Can't make '%s'.",s);
- exit(-1);
- } else /* exists - assume it's up to date since we don't know */
- return(latest);
- }
-
- if (defnp->uptodate)
- return(defnp->modified);
-
- /* now make sure everything that it depends on is up to date */
- latest = 0;
- depp = defnp->dependson;
- while (depp != NULL) {
-
- latest = max(make(depp->name),latest);
- depp = depp->nextdep;
- }
-
- knowhow = TRUE; /* has dependencies therefore we know how */
-
- /* if necessary, execute all of the commands to make it */
- /* if (out of date) || (depends on nothing) */
- if (latest > defnp->modified || defnp->dependson==NULL) {
- /* make those suckers */
- howp = defnp->howto;
- while (howp != NULL) {
- /* printf("%s %s\n",howp->howcom,howp->howargs); */
- if (execute) {
- char filename[100]; /* extra space */
- if (1) {
- if (execl(howp->howcom,howp->howargs) != 0) {
- fprintf(stderr,
- "Make: error from %s",howp->howcom);
- if (stopOnErr)
- exit(-1);
- }
- } else {
- fprintf(stderr,"Make: Can't find '%s'.",
- howp->howcom);
- if (stopOnErr)
- exit(-1);
- }
- putchar('\n'); /* in case command leaves us dangling */
- }
- howp = howp->nexthow;
- }
- /* Only say it`s as recent as it's latest dependent - that way
- if we don't actually have a file for this dependency, it works
- ok
- */
- defnp->modified = latest;
- defnp->uptodate = TRUE;
- if (defnp->howto != NULL) /* we had instructions */
- madesomething = TRUE;
- }
-
- return(defnp->modified);
-
- }
-
-
- add_do(s)
- char *s;
- {
- struct dorec *ptr1, *ptr2;
- char *getmem();
-
- ptr1 = getmem(sizeof(struct dorec));
-
- ptr1->name = s; /* okay since only called with an argv */
- ptr1->nextdo = NULL;
-
- uppercase(ptr1->name);
-
- /* now go down the dolist */
- if (dolist == NULL)
- dolist = ptr1;
- else {
- ptr2 = dolist;
- while (ptr2->nextdo != NULL)
- ptr2 = ptr2->nextdo;
- ptr2->nextdo = ptr1;
- }
-
- }
-
-
- readmakefile(s)
- char *s;
- {
- FILE *fil;
-
- int doneline, pos, i, j;
- char inline[INMAX], info[INMAX];
- char *getmem();
- struct defnrec *defnp, *defnp2;
- struct deprec *depp, *depp2;
- struct howrec *howp, *howp2;
-
- if ( (fil = fopen(s,"r")) < 0) {
- fprintf(stderr,"Make: Couldn't open '%s'.",s);
- return;
- }
-
- while (fgets(inline,INMAX,fil) != NULL) {
-
- inline[strlen(inline) - 1] = '\0';
-
- if (inline[0] == '\0') /* ignore blank lines */
- continue;
-
- if (!isspace(inline[0])) { /* start of a new definition */
- uppercase(inline);
-
- /* get what we're defining into info */
- if (sscanf(inline,"%s ",info) != 1) {
- fprintf(stderr,"Make: Can't scan: '%s'.",inline);
- continue;
- }
-
- /* test for wildcards in file being defined */
- for(i=0;info[i]!='\0';i++)
- if (s[i]=='?' || s[i]=='*') {
- fprintf(stderr,"Make: Definition of '%s'.",info);
- fprintf(stderr," contains wildcard.");
- break;
- }
-
- /* get a new struct */
- defnp = getmem(sizeof(struct defnrec));
- /* add it to the end of defnlist */
- if (defnlist == NULL)
- defnlist = defnp;
- else {
- defnp2 = defnlist;
- while (defnp2->nextdefn != NULL)
- defnp2 = defnp2->nextdefn;
- defnp2->nextdefn = defnp;
- }
- /* initialize it */
-
- defnp->name = getmem(strlen(info)+1);
- strcpy(defnp->name,info);
-
- if(no_file) {
- add_do(defnp->name);
- no_file = 0;
- }
-
- defnp->uptodate = FALSE; /* actually unknown */
- defnp->modified = getmodified(defnp->name,DEFINED);
- defnp->dependson = NULL;
- defnp->howto = NULL;
- defnp->nextdefn = NULL;
-
- /* now go through all of its dependecies */
- /* first move past the first name */
- pos = 0;
- while (isspace(inline[pos]))
- pos++;
- while (!isspace(inline[pos]) && inline[pos]!='\0')
- pos++;
- /* now loop through those suckers */
- doneline = FALSE;
- while (!doneline) {
- while (isspace(inline[pos]))
- pos++;
- if (inline[pos] == '\0') {
- doneline = TRUE;
- continue;
- }
- for(i = 0; !isspace(inline[pos]) && inline[pos]!='\0'; )
- info[i++] = inline[pos++];
- info[i] = '\0';
- /* get a new struct */
- depp = getmem(sizeof(struct deprec));
- /* add it to the end of deplist */
- if (defnp->dependson == NULL)
- defnp->dependson = depp;
- else {
- depp2 = defnp->dependson;
- while (depp2->nextdep != NULL)
- depp2 = depp2->nextdep;
- depp2->nextdep = depp;
- }
- depp->name = getmem(strlen(info)+1);
- strcpy(depp->name,info);
- depp->nextdep = NULL;
- }
- } else { /* a how to line that starts with blank or tab */
- if (defnp == NULL) {
- fprintf(stderr,"Make: Howto line without a definition.");
- fprintf(stderr,"Make: '%s'.",inline);
- }
- /* now split the line up into command and args */
- for (pos=0;isspace(inline[pos]); pos++);
- ;
- for (i=pos; !isspace(inline[i]) && inline[i]!='\0'; i++)
- ;
- /* if there is something there, allocate mem and copy */
- if (i != pos) {
- /* get a new struct */
- howp = getmem(sizeof(struct howrec));
- /* add it to the end of howlist */
- if (defnp->howto == NULL)
- defnp->howto = howp;
- else {
- howp2 = defnp->howto;
- while (howp2->nexthow != NULL)
- howp2 = howp2->nexthow;
- howp2->nexthow = howp;
- }
- /* copy command filename */
- howp->howcom = getmem(i-pos+1);
- for(j=0; pos < i; )
- howp->howcom[j++] = inline[pos++];
- howp->howcom[j] = '\0';
- /* now look for any argumentative part */
- while (isspace(inline[pos]))
- pos++;
- howp->howargs = getmem(strlen(inline)-pos + 1);
- for(i=0; inline[pos] != '\0'; )
- howp->howargs[i++] = inline[pos++];
- howp->howargs[i] = '\0';
- howp->nexthow = NULL;
- }
- }
- }
- }
-
-
- uppercase(s)
- char *s;
- {
- for( ; *s != '\0'; s++)
- *s = toupper(*s);
- }
-
-
- char *getmem(size)
- int size;
- {
- char *p;
- if ((p = malloc(size)) == 0) {
- fprintf(stderr,"Make: Ran out of memory.");
- exit(-1);
- }
- return(p);
- }
-
-
- long getmodified(name,which)
- char *name;
- int which;
- {
- static int save_es, dta_seg, dta_offset;
- long datetime, dateof(), max(), min();
-
- datetime = 0; /* as old as possible if does not exist */
- set_dta();
- if (find_first(name) == 0) { /* at least one matching file exists */
- datetime = dateof();
- /* now loop through all the rest of the matching files */
- while (find_next() == 0) {
- if (which == DEPENDANT)
- datetime = max(datetime, dateof());
- else /* this is DEFINED */
- datetime = min(datetime, dateof());
- }
- } else /* doesn't exist */
- datetime = 0; /* as old as possible */
- return(datetime);
- }
-
- long max(a,b)
- long a,b;
- {
- return(a>b ? a : b);
- }
-
- long min(a,b)
- long a,b;
- {
- return(a>b ? b : a);
- }